package myJs.common

import com.softwaremill.quicklens._
import myJs.{CpLayer, MyPages}
import myJs.Implicits._
import myJs.api.Api
import myJs.common.loadSample.LabCp
import myJs.cps.{ImageSelectCp, PureDatePickerCp}
import myJs.myPkg.reactHookForm.{ReactHookForm, UseFormOptions}
import myJs.myPkg._
import myJs.tool.Tool
import org.scalajs.dom.{File, FormData, URLSearchParams}
import org.scalajs.macrotaskexecutor.MacrotaskExecutor.Implicits._
import shared.pojo.FreezerSet.FreezerSetData
import shared.pojo.Pojo.ValidData
import shared.pojo.Sample._
import slinky.core.FunctionalComponent
import slinky.core.annotations.react
import slinky.core.facade.Hooks.{useEffect, useState}
import slinky.web.html._

import scala.collection.immutable.SeqMap
import scala.scalajs.js
import scala.scalajs.js.JSON
import upickle.default._

import scala.util.{Failure, Success}

/**
 * Created by yz on 21/1/2022
 */
@react object EditSampleFormCp {

  case class Props(updated2Page: MyPages)

  val component = FunctionalComponent[Props] { props =>

    val location = ReactRouterDOM.useLocation()
    val searchParams = new URLSearchParams(location.search)
    val curId = searchParams.get("id")
    val navigate = ReactRouterDOM.useNavigate()

    val (idV, setIdV) = useState(curId)
    val (sampleInfo, setSampleInfo) = useState(SampleInfo(tests = List.empty))
    val (filess, setFiless) = useState(List[List[File]]())
    val (files, setFiles) = useState(List[File]())
    val (rowNumberMap, setRowNumberMap) = useState(SeqMap("" -> "无"))
    val (colNumberMap, setColNumberMap) = useState(SeqMap("" -> "无"))

    val useForm = ReactHookForm.useForm(UseFormOptions(mode = "onChange"))

    object FTool {

      def refreshRowColMap = {
        val request = FreezerSetData(freezerNumber = sampleInfo.freezerNumber,
          freezerLayerNumber = sampleInfo.freezerLayerNumber)
        Api.freezerSet.get(request).map { op =>
          val (curRowNumberMap, curColNumberMap) = if (request.freezerNumber.nonBlank && request.freezerLayerNumber.nonBlank) {
            val curFreezerSet = op.getOrElse(FreezerSetData())
            val rowNumberMap = SeqMap("" -> "无") ++ (1 to curFreezerSet.totalRowNumber.toInt).map(_.toString).toList.optionMap
            val colNumberMap = SeqMap("" -> "无") ++ (1 to curFreezerSet.totalColNumber.toInt).map(_.toString).toList.optionMap
            (rowNumberMap, colNumberMap)
          } else {
            (SeqMap("" -> "无"), SeqMap("" -> "无"))
          }
          setRowNumberMap(curRowNumberMap)
          setColNumberMap(curColNumberMap)
        }.onComplete {
          case Success(value) =>
          case Failure(e) =>
            e.printStackTrace()
        }
      }


      def refreshSampleInfo = {
        val options = Tool.layerOptions.copy(shade = List("0.1", "#fff"))
        val index = layer.load(0, options)
        Api.sample.getById(idV).map { curSampleInfo =>
          val newFiless = curSampleInfo.workflow.map(x => List.empty[File])
          setFiless(newFiless)
          setSampleInfo(curSampleInfo)
          layer.close(index)
          useForm.reset(curSampleInfo)
        }
      }

      def filesChange = (vs: List[File]) => {
        setFiles(vs)
      }

      def update = () => {
        val freezerTexts = List(sampleInfo.freezerNumber, sampleInfo.freezerLayerNumber, sampleInfo.rowNumber,
          sampleInfo.colNumber)
        val freezerInfoNoValid = freezerTexts.exists(_.nonBlank) && freezerTexts.exists(_.isBlank)
        if (freezerInfoNoValid) {
          layer.msg("冰箱信息不完整!", LayerOptions(icon = 5, time = 3000))
        } else {
          val index = layer.alert(Tool.myElement, Tool.layerOptions)
          val formData = new FormData()
          files.zipWithIndex.foreach { case (file, curI) =>
            formData.append(s"labFiles", file)
          }
          formData.append("sampleInfo", write(sampleInfo))
          Api.sample.update(formData) { str =>
            layer.close(index)
            val response = read[ValidData](str)
            if (response.valid) {
              swal(SwalOptions(title = "成功", text = "更新成功!", `type` = "success"))
              navigate(s"${props.updated2Page.absolutePath}")
            } else {
              val options = SwalOptions(title = "错误", text = response.message, `type` = "error")
              swal(options)
            }

          }
        }
        ()
      }

      val removeImg = (curI: Int) => {
        val curUris = sampleInfo.images.removedByI(curI)
        val curSampleInfo = sampleInfo.modify(_.images).setTo(curUris)
        setSampleInfo(curSampleInfo)
      }

      val imagesAdd = (curUris: List[String]) => {
        val curImages = sampleInfo.images ::: curUris
        val curSampleInfo = sampleInfo.modify(_.images).setTo(curImages)
        setSampleInfo(curSampleInfo)
      }

      def freezerNumberChange = (v: String) => {
        val curSampleInfo = sampleInfo.modify(_.freezerNumber).setTo(v)
        setSampleInfo(curSampleInfo)
      }

      def removeServerImg = (curI: Int) => {
        val curUris = sampleInfo.serverImages.removedByI(curI)
        val curSampleInfo = sampleInfo.modify(_.serverImages).setTo(curUris)
        setSampleInfo(curSampleInfo)
      }

      def dateChange = (v: String) => {
        val curSampleInfo = sampleInfo.modify(_.date).setTo(v)
        setSampleInfo(curSampleInfo)
      }

      def addressChange = (v: String) => {
        val curSampleInfo = sampleInfo.modify(_.address).setTo(v)
        setSampleInfo(curSampleInfo)
      }

      def elevationChange = (v: String) => {
        val curSampleInfo = sampleInfo.modify(_.elevation).setTo(v)
        setSampleInfo(curSampleInfo)
      }

      def sampleLineNumberChange = (v: String) => {
        val curSampleInfo = sampleInfo.modify(_.sampleLineNumber).setTo(v)
        setSampleInfo(curSampleInfo)
      }

      def longitudeChange = (v: String) => {
        val curSampleInfo = sampleInfo.modify(_.longitude).setTo(v)
        setSampleInfo(curSampleInfo)
      }

      def latitudeChange = (v: String) => {
        val curSampleInfo = sampleInfo.modify(_.latitude).setTo(v)
        setSampleInfo(curSampleInfo)
      }

      def sampleTypeChange = (v: String) => {
        val curSampleInfo = sampleInfo.modify(_.sampleType).setTo(v)
        setSampleInfo(curSampleInfo)
      }

      def freshnessChange = (v: String) => {
        val curSampleInfo = sampleInfo.modify(_.freshness).setTo(v)
        setSampleInfo(curSampleInfo)
      }

      def gathererChange = (v: String) => {
        val curSampleInfo = sampleInfo.modify(_.gatherer).setTo(v)
        setSampleInfo(curSampleInfo)
      }

      def weatherChange = (v: String) => {
        val curSampleInfo = sampleInfo.modify(_.weather).setTo(v)
        setSampleInfo(curSampleInfo)
      }

      def takeOut = () => {
        val curSampleInfo = sampleInfo.modify(_.freezerNumber).setTo("").modify(_.freezerLayerNumber).setTo("").
          modify(_.rowNumber).setTo("").modify(_.colNumber).setTo("")
        setSampleInfo(curSampleInfo)
      }

      def freezerLayerNumberChange = (v: String) => {
        setSampleInfo(sampleInfo.modify(_.freezerLayerNumber).setTo(v))
      }

      def rowNumberChange = (v: String) => {
        setSampleInfo(sampleInfo.modify(_.rowNumber).setTo(v))
      }

      def colNumberChange = (v: String) => {
        setSampleInfo(sampleInfo.modify(_.colNumber).setTo(v))
      }

      def sampleInfoChange = (v: SampleInfo) => {
        setSampleInfo(v)
      }

    }

    useEffect(() => {
      FTool.refreshSampleInfo
    }, List()
    )

    useEffect(() => {
      FTool.refreshRowColMap
    }, List(sampleInfo.freezerNumber, sampleInfo.freezerLayerNumber)
    )

    form(className := "form-horizontal", onSubmit := {
      useForm.handleSubmit((data: js.Dictionary[js.Any]) => {
        println(JSON.stringify(data))
        FTool.update()
      })
    },
      h4("基本信息"),
      div(className := "form-group",
        label(className := "control-label col-sm-2", "样本编号:"),
        div(className := "col-sm-4",
          PureInputCp(useForm = useForm, name = "id", value = idV, onChange = (v: String) => setIdV(v),
            readOnly = true)
        )
      ),

      div(className := "form-group",
        label(className := "control-label col-sm-2", "日期:"),
        div(className := "col-sm-4",
          PureDatePickerCp(placeHolder = s"", name = "endTime", value = sampleInfo.date,
            onChangeF = FTool.dateChange)
        ),
        label(className := "control-label col-sm-2", "地点:"),
        div(className := "col-sm-4",
          PureInputCp(useForm = useForm, name = "address", value = sampleInfo.address,
            onChange = FTool.addressChange,
          )
        )
      ),

      div(className := "form-group",
        label(className := "control-label col-sm-2", "海拔:"),
        div(className := "col-sm-4",
          PureInputCp(useForm = useForm, name = "elevation", value = sampleInfo.elevation,
            onChange = FTool.elevationChange,
          )
        ),
        label(className := "control-label col-sm-2", "样线号:"),
        div(className := "col-sm-4",
          PureInputCp(useForm = useForm, name = "sampleLineNumber", value = sampleInfo.sampleLineNumber,
            onChange = FTool.sampleLineNumberChange,
          )
        ),
      ),

      div(className := "form-group",
        label(className := "control-label col-sm-2", "经度:"),
        div(className := "col-sm-4",
          PureInputCp(useForm = useForm, name = "longitude", value = sampleInfo.longitude,
            onChange = FTool.longitudeChange,
          )
        ),
        label(className := "control-label col-sm-2", "纬度:"),
        div(className := "col-sm-4",
          PureInputCp(useForm = useForm, name = "latitude", value = sampleInfo.latitude,
            onChange = FTool.latitudeChange,
          )
        ),
      ),

      div(className := "form-group",
        label(className := "control-label col-sm-2", "样品类型:"),
        div(className := "col-sm-4",
          PureInputCp(useForm = useForm, name = "sampleType", value = sampleInfo.sampleType,
            onChange = FTool.sampleTypeChange,
          )
        )
      ),

      div(className := "form-group",
        label(className := "control-label col-sm-2", "样品照片:"),
        div(className := "col-sm-10",
          ImageSelectCp(serverImages = sampleInfo.serverImages, images = sampleInfo.images,
            removeImg = FTool.removeImg, imagesAdd = FTool.imagesAdd, id = sampleInfo.id,
            removeServerImg = FTool.removeServerImg)
        )
      ),

      div(className := "form-group",
        label(className := "control-label col-sm-2", "新鲜程度:"),
        div(className := "col-sm-4",
          PureInputCp(useForm = useForm, name = "freshness", value = sampleInfo.freshness,
            onChange = FTool.freshnessChange,
          )
        ),
        label(className := "control-label col-sm-2", "采集人:"),
        div(className := "col-sm-4",
          PureInputCp(useForm = useForm, name = "gatherer", value = sampleInfo.gatherer,
            onChange = FTool.gathererChange,
          )
        )
      ),

      div(className := "form-group",
        label(className := "control-label col-sm-2", "天气:"),
        div(className := "col-sm-4",
          PureInputCp(useForm = useForm, name = "weather", value = sampleInfo.weather,
            onChange = FTool.weatherChange,
          )
        ),
      ),

      h4("冰箱信息"),

      div(className := "form-group",
        div(className := "actions col-sm-offset-2 col-sm-6",
          button(`type` := "button", className := "btn btn-default", onClick := FTool.takeOut,
            span(className := "fa fa-long-arrow-up", s" 取出")
          ),
        ),
      ),

      div(className := "form-group",
        label(className := "control-label col-sm-2", "冰箱编号:"),
        div(className := "col-sm-4",
          PureRSelectCp(useForm = useForm, name = "freezerNumber", value = sampleInfo.freezerNumber,
            onChange = FTool.freezerNumberChange, optionMap = Tool.freezerNumberMap
          )
        ),
        label(className := "control-label col-sm-2", "层数:"),
        div(className := "col-sm-4",
          PureRSelectCp(useForm = useForm, name = "freezerLayerNumber", value = sampleInfo.freezerLayerNumber,
            onChange = FTool.freezerLayerNumberChange, optionMap = Tool.freezerLayerNumberMap
          )
        )
      ),

      div(className := "form-group",
        label(className := "control-label col-sm-2", "行数:"),
        div(className := "col-sm-4",
          PureRSelectCp(useForm = useForm, name = "rowNumber", value = sampleInfo.rowNumber,
            onChange = FTool.rowNumberChange, optionMap = rowNumberMap
          )
        ),
        label(className := "control-label col-sm-2", "列数:"),
        div(className := "col-sm-4",
          PureRSelectCp(useForm = useForm, name = "colNumber", value = sampleInfo.colNumber,
            onChange = FTool.colNumberChange, optionMap = colNumberMap
          )
        )
      ),

      CommentCp(useForm = useForm, sampleInfo = sampleInfo, sampleInfoChange = FTool.sampleInfoChange),

      LabCp(useForm = useForm, sampleInfo = sampleInfo, sampleInfoChange = FTool.sampleInfoChange, files = files,
        filesChange = FTool.filesChange),

      h4("测试信息"),

      TestInfoCp(useForm = useForm, sampleInfo = sampleInfo, sampleInfoChange = FTool.sampleInfoChange),

      div(className := "form-group",
        div(className := "actions col-sm-offset-2 col-sm-2",
          button(`type` := "submit", className := "btn btn-primary myAddShow",
            s" 更新",
          ),
        )
      )
    )
  }


}
